/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.nativelibs4java.buswing;

import java.util.ArrayList;
import java.util.List;

abstract class PersistentItems<I extends PersistentItems.PersistentItem> {

    long lastPersistentItemId;

    static class PersistentItem {

        public int getUnderlyingIndex() {
            return mutableItemIndex;
        }
        void setIndex(int index) {
            mutableItemIndex = index;
        }

        private int mutableItemIndex;
        final long persistentId;

        public PersistentItem(long persistentId, int rowIndex) {
            this.mutableItemIndex = rowIndex;
            this.persistentId = persistentId;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (obj.getClass() != getClass()) {
                return false;
            }
            return ((PersistentItem) obj).persistentId == persistentId;
        }

        public int hashCode() {
            return new Long(persistentId).hashCode();
        }
    }

    protected abstract I createItem(long persistentId, int itemIndex);
    List<I> items = new ArrayList<I>();

    long createPersistentId() {
        synchronized (PersistentItem.class) {
            return lastPersistentItemId++;
        }
    }
    public I getItem(int itemIndex, boolean create) {
        if (itemIndex >= items.size()) {
            for (int i = 0, n = itemIndex + 1 - items.size(); i < n; i++) {
                items.add(null);
            }
        }
        I item = items.get(itemIndex);
        if (item == null && create) {
            items.set(itemIndex, item = createItem(createPersistentId(), itemIndex));
        }
        return item;
    }

    void itemInserted(int index, int count) {
        for (int i = index, n = items.size(); i < n; i++) {
            I item = items.get(i);
            if (item == null) {
                continue;
            }
            item.setIndex(item.getUnderlyingIndex() + count);
        }
        for (int i = 0; i < count; i++) {
            items.add(index, null);
        }
    }

    void itemRemoved(int index, int count) {
        for (int i = index + 1, n = items.size(); i < n; i++) {
            I item = items.get(i);
            if (item == null) {
                continue;
            }
            item.setIndex(item.getUnderlyingIndex() - count);
        }
        for (int i = 0; i < count; i++) {
            I removed = items.remove(index);
            if (removed != null) {
                removed.setIndex(-1);
            }
        }
    }
}
